package com.jumper.property.comparer.core.formatter;


import com.jumper.property.comparer.core.DiffUtil;
import com.jumper.property.comparer.core.constant.FormatConstant;
import com.jumper.property.comparer.core.diff.DiffVal;
import com.jumper.property.comparer.core.diff.value.DiffEditRow;
import com.jumper.property.comparer.core.result.DiffResult;
import com.jumper.property.comparer.core.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

public class ArrayDiffBodyFormatter extends AbstractDiffFormatter {

    private final String propertyName;
    private final DiffEditRow row;

    public ArrayDiffBodyFormatter(String propertyName, DiffEditRow row) {
        this.propertyName = propertyName;
        this.row = row;
    }

    @Override
    public String format() {
        DiffResult rst = DiffUtil.resolve(row.getSetting().getObjectSetting().getCls(), row.getBeforeData(), row.getAfterData());
        if (!rst.isHasDiff()) {
            return null;
        }
        boolean fullProperties = getFullProperties();
        String format = pattern.getArrayDiffBodyPattern(fullProperties)
                .replace(FormatConstant.DISPLAY_PROPERTY_KEY, propertyName)
                .replace(FormatConstant.ROW_CHANGE_MODE_KEY, getChangeMode())
                .replace(FormatConstant.UNION_PROPERTY_VALUES_KEY, StringUtils.defaultIfBlank(row.getDisplayName(), row.getRowKey()));
        if (fullProperties) {
            format = format.replace(FormatConstant.ROW_CHANGE_DATA_KEY, getChangeData(rst.getDiffValList()));
        }
        return format;
    }

    private String getChangeData(List<DiffVal> diffValList) {
        List<String> diffValues = diffValList.stream().map(DiffVal::getDiffValue).collect(Collectors.toList());
        return String.join(pattern.getInlineJoinDiffPattern(), diffValues);
    }

    private String getChangeMode() {
        if (row.getBeforeData() == null) {
            return pattern.getArrayAddDiffPattern();
        }
        if (row.getAfterData() == null) {
            return pattern.getArrayRemoveDiffPattern();
        }
        return pattern.getArrayUpdateDiffPattern();
    }

    private boolean getFullProperties() {
        return row.getBeforeData() != null && row.getAfterData() != null || row.getSetting().isWhenArrayFullProperties();
    }
}
